package 多线程初阶.示例测试;
import java.util.concurrent.PriorityBlockingQueue;
/**
 * 定时器的实现
 */
class MyTimeTask implements Comparable<MyTimeTask>{
    private Runnable command;    //具体的任务
    private long time;//做任务的具体时间
    public MyTimeTask(Runnable command,long after){//构造方法
        this.command=command;
        this.time=after+System.currentTimeMillis();//取的是绝对时间
    }
    public long getTime() {
        return time;
    }
    public void run(){
        command.run();
    }

    @Override
    public int compareTo(MyTimeTask o) {
        return (int)(this.time-o.time);
    }
}
class MyTimer{
    private PriorityBlockingQueue<MyTimeTask> queue=new PriorityBlockingQueue<>();
    private Object locker=new Object();
    public void schedule(Runnable command,long after){
        MyTimeTask myTimeTask=new MyTimeTask(command,after);
        synchronized (locker){
            queue.put(myTimeTask);
            locker.notify();//唤醒扫描线程,由于线程此时可能处于阻塞状态,传入一个执行时间更短的task,就要优先安排执行,所以需要唤醒,唤醒一下也没什么坏处
        }
    }
    public MyTimer(){
        Thread thread=new Thread(()->{
           while(true){
               try{
                   synchronized (locker){
                       while (queue.isEmpty()){
                           locker.wait();//当有task传入的时候,这里就被唤醒
                       }
                       MyTimeTask myTimeTask=queue.take();
                       long curTime=System.currentTimeMillis();
                       if(myTimeTask.getTime()>curTime){
                           queue.put(myTimeTask);
                           locker.wait(myTimeTask.getTime()-curTime);
                       }else{
                           myTimeTask.run();
                       }
                   }
               }catch (InterruptedException e){
                   e.printStackTrace();
               }
           }
        });
        thread.start();
    }
}

public class TestDemo22 {
    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("3333");
            }
        }, 6000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("2222");
            }
        }, 4000);
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("1111");
            }
        }, 2000);
    }
}
